﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using SdmxMl.Common;
using SdmxMl.Manager;
using SdmxMl.Structure;
using SdmxMl.GenericMetadata;
using SdmxMl.SanteSuisse;

namespace SilcQuest.CSV
{
    public class ExportCsvQuest : CsvExportBase
    {
        private StreamWriter sw;
        private SmManager sm;
        protected RefVarHelper varHelper;

        public ExportCsvQuest(SmManager smgr, string path, char delimiter)
            : base(delimiter)
        {
            sm = smgr;
            varHelper = new RefVarHelper(sm);
            sw = new StreamWriter(path, false, Encoding.Default);
        }

        public void Close()
        {
            sw.Flush();
            sw.Close();
        }

        public void WriteQuest(MetadataSetType metaSet, bool writeHeader, string[]arrLang, bool giveCodes, int maxCodes)
        {
            MetadataStructureDefinitionType msd = sm.GetArtefact(SdmxArtefactType.MetadataStructureDefinitions, metaSet.MetadataStructureRef, true) as MetadataStructureDefinitionType;
            //ReportStructureType report = msd.ReportStructureList.LocateItem(metaSet.ReportRef);
            // Force full report even if technical quest

            bool isTechnical = metaSet.ReportRef == "R_SILC_TECH";

            ReportStructureType report = msd.ReportStructureList[0];
            int keyCount = msd.TargetIdentifiers.FullTargetIdentifier.IdentifierComponentList.Count + 1;

            int colCount = 0;
            // Column count depends of languages requested
            foreach (MetadataAttributeType meta in report.MetadataAttributeList)
            {
                // if multilingual or codelist with code provide requested languages
                if (meta.TextFormat.isMultiLingual ||
                    (giveCodes && meta.TextFormat.TextType == TextTypeType.URI && meta.ConceptInfo.Id != "CONCEPT_URN"))
                    colCount += arrLang.Length;
                else
                    ++colCount;
            }
            int count = keyCount + colCount;
            int col = 1;
            if (writeHeader)
            {
                // Signal if technical or not
                AddCell(sw, col++, count, "TECH", true);

                // Keys
                foreach (IdentifierComponentType key in msd.TargetIdentifiers.FullTargetIdentifier.IdentifierComponentList)
                    AddCell(sw, col++, count, key.Id, true);

                // reported attributes Values
                foreach (MetadataAttributeType meta in report.MetadataAttributeList)
                {
                    // if multilingual or codelist with code provide requested languages
                    if (meta.TextFormat.isMultiLingual ||
                        (giveCodes && meta.TextFormat.TextType == TextTypeType.URI && meta.ConceptInfo.Id != "CONCEPT_URN"))
                    {
                        foreach (string l in arrLang)
                            AddCell(sw, col++, count, meta.ConceptInfo.Id + "_" + l.ToLower(), true);
                    }
                    else
                    {
                        AddCell(sw, col++, count, meta.ConceptInfo.Id, true);
                    }
                }
            }

            // Now content
            foreach (AttributeValueSetType atr in metaSet.AttributeValueSetList)
            {
                CatiSilcQuestion question = new CatiSilcQuestion(varHelper, atr, arrLang[0]);
                question.UseCrLfInCode = false;
                question.MaxCodes = maxCodes;

                // Is technical
                col = 1;
                AddCell(sw, col++, count, isTechnical ? "1" : "2", true);
                // Keys values
                foreach (IdentifierComponentType key in msd.TargetIdentifiers.FullTargetIdentifier.IdentifierComponentList)
                    if (key.Id == "YEAR")
                    {
                        int decade = Convert.ToInt32(question.Deceny);
                        decade += 2000;
                        AddCell(sw, col++, count, decade.ToString(), true);

                    }
                    else
                    {
                        AddCell(sw, col++, count, atr.TargetValuesTypeList[key.Id], true);
                    }

                // Meta part, transmit code & code text
                foreach (MetadataAttributeType meta in report.MetadataAttributeList)
                {
                    ReportedAttributeType ra = atr.ReportedAttributeList.GetReportedAttributeOfConcept(meta.ConceptInfo.Id);
                    string val = string.Empty;

                    // if multilingual or codelist with code provide requested languages
                    if (meta.TextFormat.isMultiLingual ||
                        (giveCodes && meta.TextFormat.TextType == TextTypeType.URI && meta.ConceptInfo.Id != "CONCEPT_URN"))
                    {
                        foreach (string l in arrLang)
                        {
                            // special retrieve text from concept or from reported attribute
                            if (meta.ConceptInfo.Id == "LABEL_OPTIONAL")
                            {
                                question.langCd = l;
                                AddCell(sw, col++, count, question.VarLabel, true);
                            }
                            else if (giveCodes && (meta.ConceptInfo.Id == "QUALITY_URN" || meta.ConceptInfo.Id == "CODELIST_URN"))
                            {
                                question.langCd = l;
                                if (meta.ConceptInfo.Id == "QUALITY_URN")
                                    AddCell(sw, col++, count, question.QualityCodes, true);
                                else
                                    AddCell(sw, col++, count, question.VarCodes, true);
                            }
                            else
                            {
                                if (ra != null)
                                    val = ra.InternationalizedValue.GetForLanguage(l);
                                AddCell(sw, col++, count, val, true);
                            }
                        }
                    }
                    else
                    {
                        if (ra != null)
                            val = ra.InternationalizedValue.GetFirst();
                        AddCell(sw, col++, count, val, true);
                    }
                }
                 
            }
        }


    }
}
